/*
 * measurement.c
 *
 *  Created on: Oct 28, 2019
 *      Author: Standa
 *
 *	This module provides fixed count (ADC_READSPERMEASPERIOD) of fast analog measurements of VM10R, VM100R and IM channels during single period (1/freq_Hz).
 *	Secondary function is to provide monitoring of VM10R, VM100R, IM, VBAT, VREF (for VDDA calculation) and TEMP when fast measurement is not active.
 *	TIM1 is the counter reserved for ADC conversion triggering and DMA1 CH1 used to transfer the converted data into memory.
 */

#include "measurement.h"
#include "error.h"
#include "adc.h"
#include "dma.h"
#include "tim.h"


#define VREF					3.3f									//Volts
#define VMRESH					51000.0f								//Ohms
#define VMRESL					5600.0f									//Ohms
#define VMCOEF					( ( VMRESH + VMRESL ) / VMRESL )		//Coef to convert ADC reading to volts

#define IMSENSR					10.0f									//Ohms
#define IMCOEF					( VREF / ( 4096 * IMSENSR ) )			//Coef to convert ADC reading to amps


#define ADCCHANNELS	2
static uint16_t ADCBuffer[ADCCHANNELS];

static float VBat, Im;


/*
 * Initialize generator module, used typically during boot only
 */
void meas_Init(void){

	VBat = 0;
	Im = 0;

	LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);								//DMA transfer must be disabled before ADC calibration
	LL_ADC_StartCalibration(ADC1);
	while(LL_ADC_IsCalibrationOnGoing(ADC1));
	LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_LIMITED);							//Activate DMA ADC to memory transfer

	//Prepare ADC trigger timer TIM1
	LL_TIM_SetCounter(TIM1, 0);																//Restart the counter
	LL_TIM_ClearFlag_UPDATE(TIM1);															//Clear update flag which might be set during configuration

	LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
	LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1, (uint32_t)(&(ADC1->DR)), (uint32_t)(ADCBuffer), LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
	LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, ADCCHANNELS);
	LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
	LL_ADC_Enable(ADC1);
	LL_ADC_REG_StartConversion(ADC1);

	LL_DMA_ClearFlag_TC1(DMA1);
	LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);

	LL_TIM_EnableCounter(TIM1);	//Start the main triggering counter

}


/*
 * Gets called by DMA1 after last measurement is transferred via DMA into buffer.
 */
void meas_EndOfADCReadingHandler(void){
	LL_DMA_ClearFlag_TC1(DMA1);

	VBat = ADCBuffer[0] * VMCOEF;
	Im = ADCBuffer[1] * IMCOEF;
}


float meas_GetVbat(void){
	return VBat;
}


float meas_GetIm(void){
	return Im;
}
